package com.ytjj.qmyx.admin.shiro;

import com.ytjj.common.exception.ApiException;
import com.ytjj.qmyx.admin.mapper.MenuMapper;
import com.ytjj.qmyx.admin.model.Admin;
import com.ytjj.qmyx.admin.model.Role;
import com.ytjj.qmyx.admin.service.AdminService;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

/**
 * 自定义 Realm
 */
@Slf4j
public class AdminRealm extends AuthorizingRealm {
    @Autowired
    private AdminService adminService;

    @Resource
    private MenuMapper menuMapper;

    private final static String SALT="test**";

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        // 添加角色和权限
        SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
        Admin admin=(Admin)principalCollection.getPrimaryPrincipal();
        if(null==admin){
            return simpleAuthorizationInfo;
        }
        // 获取登录邮箱
        String email = admin.getEmail();
        log.info("doGetAuthorizationInfo,email={}"+email);

        // 根据手机号去获取改用户的角色
        List<Role> roles = adminService.getRoleByEmail(email);
        if(roles!=null && roles.size()>0){
            for (Role role : roles) {
                //添加角色
                simpleAuthorizationInfo.addRole(role.getId().toString());

                List<String> apiCodeList = new ArrayList<>();
                //如果角色为超级管理员
                if (1 == role.getId()){
                    //获取全部接口权限
                    apiCodeList = menuMapper.selectApiCode();
                }else {
                    // 用户角色下的所有接口权限
                    apiCodeList = adminService.getApiCodeList(role.getId());
                }
                //添加权限
                for (String code : apiCodeList) {
                    simpleAuthorizationInfo.addStringPermission(code);
                }
            }
        }
        return simpleAuthorizationInfo;
    }

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        //加这一步的目的是在Post请求的时候会先进认证，然后在到请求
        if (authenticationToken.getPrincipal() == null) {
            return null;
        }
        //获取用户手邮箱
        String email = authenticationToken.getPrincipal().toString();
        log.info("doGetAuthenticationInfo,email={}",email);
        Admin admin = adminService.getAdminByEmail(email);
        if (admin == null) {
            //这里返回后会报出对应异常
            throw new ApiException("该邮箱{"+email+"}的账号不存在或已停用！");
        } else {
            //这里验证authenticationToken和simpleAuthenticationInfo的信息
            SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(admin, admin.getPwd(), getName());
            // 加盐的方式可随机字符
            simpleAuthenticationInfo.setCredentialsSalt(ByteSource.Util.bytes(SALT));
            return simpleAuthenticationInfo;
        }
    }

    //清除缓存
    public void clearCached() {
        PrincipalCollection principals = SecurityUtils.getSubject().getPrincipals();
        super.clearCache(principals);
    }
}
